package com.xframe.xdal.core;


import com.xframe.xdal.core.autofill.AutoProcRuntime;
import com.xframe.xdal.config.IDataSourceConfig;
import com.xframe.xdal.core.constant.*;
import com.xframe.xdal.core.domain.SysBaseEntity;
import com.xframe.xdal.core.domain.XDynamicModel;
import com.xframe.xdal.core.exception.*;
import com.xframe.xdal.core.handler.BeanHandlerOptions;
import com.xframe.xdal.core.handler.BeanListHandler;
import com.xframe.xdal.core.handler.BeanObjectHandler;
import com.xframe.xdal.core.handler.XDynamicModelListHandler;
import com.xframe.xdal.core.manage.BaseDbManage;
import com.xframe.xdal.core.model.*;
import com.xframe.xdal.core.model.mapping.IColumnMapping;
import com.xframe.xdal.core.model.mapping.ITableInfo;
import com.xframe.xdal.core.model.mapping.TableInfoBuilder;
import com.xframe.xdal.core.model.page.IPagerModel;
import com.xframe.xdal.core.model.page.PagerModel;
import com.xframe.xdal.core.model.sqlbuilder.*;
import com.xframe.xdal.core.serialize.BaseJsonSer;
import com.xframe.xdal.core.tran.DbTransactionContext;
import com.xframe.xdal.core.tran.IDbTransaction;
import com.xframe.xdal.core.util.CollectionUtil;
import lombok.AccessLevel;
import lombok.Data;
import lombok.Setter;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.lang.Nullable;


import java.sql.SQLException;
import java.util.*;

/**
 * 功能描述:关系数据库基本通用操作封装实现
 *
 * @author xufeng
 * @version 1.0
 * @date 2022-09-28
 */
@Data
@Log4j2
public class DataBaseAccess implements AutoCloseable {

    /**
     * 数据源
     */
    @Setter(AccessLevel.NONE)
    private XDataSource dataSource;

    /**
     * 自动填充对象
     */
    @Setter(AccessLevel.NONE)
    private AutoProcRuntime autoProcRuntime = AutoProcRuntime.getInstance();

    /**
     * 销毁状态 true 为销毁  false 为未销毁
     */
    @Setter(AccessLevel.NONE)
    private Boolean isDestroyed = false;

    /**
     * 数据库管理对象
     */
    public BaseDbManage getDbManage() {
        return dataSource.getDbManage();
    }


    /**
     * 根据主键查询指定类型的实体
     *
     * @param dataSourceTypeEnums 数据库类型
     * @param dataSourceName      数据库连接名称
     * @param host                主机名
     * @param port                端口号
     * @param username            主机名
     * @param password            密码
     * @param databaseName        数据库名称
     *
     */
    private DataBaseAccess(DataSourceTypeEnums dataSourceTypeEnums, String dataSourceName,
                          String host, Integer port, String username,
                          String password, String databaseName) {
        dataSource = new XDataSource(dataSourceTypeEnums, dataSourceName, host, port, username, password, databaseName, DbManageConstants.SQLSERVER_DBO);
        dataSource.init();
    }

    private static Map<String,DataBaseAccess> dbMap = new HashMap<>(8);


    public static Map<String,DataBaseAccess> getDataBaseAccessMap(){
        return dbMap;
    }

    private static String defName = null;
    /**
     * 返回默认的数据库访问类
     *
     * @return DataBaseAccess对象
     */
    public static DataBaseAccess getInstance(){
        return dbMap.get(defName);
    }
    /**
     * 按照名称来返回数据库访问类
     * @param dataSourceName 数据源名称
     *
     * @return DataBaseAccess对象
     */
    public static DataBaseAccess getInstanceByName(String dataSourceName){
        return dbMap.get(dataSourceName);
    }

    private DataBaseAccess(IDataSourceConfig dataSourceConfig){

        dataSource = new XDataSource(dataSourceConfig.getDataSourceTypeName(),
                dataSourceConfig.getDataSourceName(), dataSourceConfig.getHost(),
                dataSourceConfig.getPort(), dataSourceConfig.getUsername(),
                dataSourceConfig.getPassword(), dataSourceConfig.getDatabaseName(), dataSourceConfig.getSchema());
        dataSource.init();
    }

    public static void registerDataSource(IDataSourceConfig dataSourceConfig){
        if(!dbMap.containsKey(dataSourceConfig.getDataSourceName())){
            dbMap.put(dataSourceConfig.getDataSourceName(),new DataBaseAccess(dataSourceConfig));
        }
        if(defName == null){
            defName = dataSourceConfig.getDataSourceName();
        }
    }

    public static void registerDataSource(DataSourceTypeEnums dataSourceTypeEnums, String dataSourceName,
                                          String host, Integer port, String username,
                                          String password, String databaseName){
        if(!dbMap.containsKey(dataSourceName)){
            dbMap.put(dataSourceName,new DataBaseAccess(dataSourceTypeEnums,dataSourceName,host,port,username,password,databaseName));
        }
        if(defName == null){
            defName = dataSourceName;
        }
    }

    public static boolean removeDataSource(String dataSourceName){
        DataBaseAccess dataBaseAccess = dbMap.get(dataSourceName);
        if(dataBaseAccess == null){
            return false;
        }
        dataBaseAccess.destroy();
        dbMap.remove(dataSourceName);
        return true;
    }


    /**
     * 根据主键查询指定类型的实体
     *
     * @param dataSourceTypeEnums 数据库类型
     * @param dataSourceName      数据库连接名称
     * @param host                主机名
     * @param port                端口号
     * @param username            主机名
     * @param password            密码
     * @param databaseName        数据库名称
     * @param schema              架构名称
     *
     */
    public DataBaseAccess(DataSourceTypeEnums dataSourceTypeEnums, String dataSourceName,
                          String host, Integer port, String username,
                          String password, String databaseName, String schema) {
        dataSource = new XDataSource(dataSourceTypeEnums, dataSourceName, host, port, username, password, databaseName, schema);
        dataSource.init();
    }

    /**
     * 根据AK主键查询指定类型的实体
     *
     * @param akQueryModel 查询条件
     *
     * @return <T>
     */
    public <T> T findByAk(AKQueryModel akQueryModel){
        DataAccessResult<T> result = findByKeyOperate(SearchFor.AK, akQueryModel.getDataType(),akQueryModel.getTableInfo(), null,
                akQueryModel.getAkValues(),akQueryModel.getAkName(),akQueryModel.getRefNames());
        if (!result.getSuccessFlag()) {
            log.error(result.getException());
            return null;
        }
        log.info("{}ms", result.getTotalDuration());
        return result.getResult();
    }
    /**
     * 根据主键查询指定类型的实体
     * @param tableInfo 对象
     * @param objectKey KEY值
     * @param refNames 引用列表
     *
     * @return <T>
     */
    public XDynamicModel findByPk(ITableInfo tableInfo, Object objectKey, String... refNames) {
        DataAccessResult<XDynamicModel> result = findByKeyOperate(SearchFor.PK,XDynamicModel.class,tableInfo,objectKey,null,"",refNames);
        if(!result.getSuccessFlag()){
            log.error(result.getException());
            return null;
        }
        log.info("{}ms",result.getTotalDuration());
        return result.getResult();
    }

    /**
     * 根据主键查询指定类型的实体
     *
     * @param dataType  被查询的数据类型
     * @param objectKey KEY值
     * @param refNames  引用列表
     * @return <T>
     */
    public <T> T findByPk(Class<?> dataType,ITableInfo tableInfo, Object objectKey, String... refNames) {
        DataAccessResult<T> result = findByKeyOperate(SearchFor.PK, dataType, tableInfo,objectKey, null, "",refNames);
        if (!result.getSuccessFlag()) {
            log.error(result.getException());
            return null;
        }
        log.info("{}ms", result.getTotalDuration());
        return result.getResult();
    }

    /**
     * 根据主键查询指定类型的实体
     *
     * @param dataType  被查询的数据类型
     * @param objectKey KEY值
     * @param refNames  引用列表
     * @return <T>
     */
    public <T> T findByPk(Class<?> dataType, Object objectKey, String... refNames) {
        DataAccessResult<T> result = findByKeyOperate(SearchFor.PK, dataType, objectKey, null, "",refNames);
        if (!result.getSuccessFlag()) {
            log.error(result.getException());
            return null;
        }
        log.info("{}ms", result.getTotalDuration());
        return result.getResult();
    }


    /**
     * 根据主键查询指定类型的实体
     *
     * @param searchFor 查询方式 PK = 主键 AK = 唯一键
     * @param dataType 被查询的数据类型
     * @param pkVal PK值
     * @param akValues AK值列表
     * @param akName AK名称
     * @param refNames 引用列表
     *
     * @return DataAccessResult<T>
     */
    public <T> DataAccessResult<T> findByKeyOperate(SearchFor searchFor, Class<?> dataType,Object pkVal,Collection<Object> akValues,String akName,String... refNames) {
        ITableInfo tableInfo = TableInfoBuilder.BuildTableInfoByAnnotation(dataType);
        return findByKeyOperate(searchFor,dataType,tableInfo,pkVal,akValues,akName,refNames);
    }

    /**
     * 根据主键查询指定类型的实体
     * @param searchFor 查询方式 PK = 主键 AK = 唯一键
     * @param tableInfo 被查询的表结构
     * @param pkVal PK值
     * @param akValues AK值列表
     * @param akName AK名称
     * @param refNames 引用列表
     *
     * @return DataAccessResult<T>
     */
    public <T> DataAccessResult<T> findByKeyOperate(SearchFor searchFor,Class<?> dataType,
                                                    ITableInfo tableInfo,Object pkVal,Collection<Object> akValues,String akName,String... refNames) {
        List<String> refList = new ArrayList<>();
        if(refNames != null){
            Collections.addAll(refList, refNames);
        }
        DataAccessResult<T> result = new DataAccessResult<>(SqlKey.SEARCH_KEY);
        SqlExpression sqlExpression = null;
        try {
            ConditionValueCollection conditionValueCollection = new ConditionValueCollection();
            if (searchFor == SearchFor.PK){

                conditionValueCollection.add(new ConditionValue(tableInfo.findPkFirst().getFieldName(), pkVal));
            }
            if(searchFor == SearchFor.AK){
                if(akValues == null || akValues.isEmpty()){
                    throw new DalFrameException(ErrorCode.ARGS_ERROR,"akValues值缺失 args = akValues");
                }
                List<IColumnMapping> columnMappingList = tableInfo.findUniqueKeyList();
                if(akValues.size() != columnMappingList.size()){
                    throw new DalFrameException(ErrorCode.ARGS_ERROR,"akValues值不匹配 args = akValues");
                }
                int index = 0;
                for(Object val:akValues){
                    conditionValueCollection.add(new ConditionValue(columnMappingList.get(index).getFieldName(), val));
                    index++;
                }
            }
            BuilderContext context = BuilderContext.create(tableInfo, dataSource.getDataSourceTypeEnums(),conditionValueCollection,
                    null,refList,null);
            BaseSqlBuilder sqlBuilder = SqlBuilderFactory.create(SqlKey.SEARCH_KEY, dataSource.getDataSourceTypeEnums());
            sqlExpression = sqlBuilder.run(context);

            BeanHandlerOptions options = new BeanHandlerOptions(tableInfo,sqlExpression.getHandlerColumnMapManage(),
                    sqlExpression.getDataSourceTypeEnums(),new BaseJsonSer(),this.autoProcRuntime);
            T bean = (T) dataSource.executeQuery(sqlExpression.getFullSql(),
                    sqlExpression.getParams(), BeanObjectHandler.create(dataType,options));
            result.setDone(bean,sqlExpression);
        }catch (AutoProcRuntimeException autoProcRuntimeException){
            result.setError(ErrorCode.AUTOFILL_ERROR,autoProcRuntimeException, null);
        }catch (SqlBuilderException sqlException){
            result.setError(ErrorCode.SQL_BUILD_ERROR,sqlException, sqlExpression);
        }catch (SQLException sqlException){
            result.setError(ErrorCode.SQL_ERROR,sqlException, sqlExpression);
        }catch (DalFrameException e) {
            result.setError(e.getCode(),e, sqlExpression);
        }catch (Exception exception) {
            result.setError(ErrorCode.DAL_UNKNOWN_ERROR,exception, sqlExpression);
        }
        return result;
    }



    /**
     * 执行一个限制了最大条数的查询的SQL查询
     *
     * @param dataType   实体类型
     * @param options   分页查询设置对象
     *
     * @return 数据表操作对象表对象
     */
    public <T> T readDataTableByMaxCount(Class<T> dataType, @Nullable FindOptions options) throws DalFrameException {
        if(options == null){
            options = FindOptions.defFindAllOptionsByMaxCount();
        }
        ITableInfo tableInfo = TableInfoBuilder.BuildTableInfoByAnnotation(dataType);
        DataAccessResult<IPagerModel<T>> result = findAllByPageOperate(dataType,tableInfo,options);
        if(!result.getSuccessFlag()){
            throw new DalFrameException(result.getCode(),result.getException().getMessage());
        }
        return (T) result.getResult().getDataList();
    }



    /**
     * 执行一个分页查询
     *
     * @param tableInfo  表结构
     * @param options   分页查询设置对象
     *
     * @return 操作结果 DataAccessResult<IPagerModel<T>>
     */
    public <T> IPagerModel<T> findAllByPage(ITableInfo tableInfo,@Nullable FindOptions options) throws DalFrameException {

        DataAccessResult<IPagerModel<T>> result = findAllByPageOperate(XDynamicModel.class,tableInfo,options);
        if(!result.getSuccessFlag()){
            throw new DalFrameException(result.getCode(),result.getException().getMessage());
        }
        return result.getResult();
    }

    /**
     * 执行一个分页查询
     *
     * @param dataType   数据类型
     * @param options   分页查询设置对象
     *
     * @return 操作结果 DataAccessResult<IPagerModel<T>>
     */
    public <T> IPagerModel<T> findAllByPage(Class<?> dataType,ITableInfo tableInfo,@Nullable FindOptions options) throws DalFrameException {

        DataAccessResult<IPagerModel<T>> result = findAllByPageOperate(dataType,tableInfo,options);
        if(!result.getSuccessFlag()){
            throw new DalFrameException(result.getCode(),result.getException().getMessage());
        }
        return result.getResult();
    }

    /**
     * 执行一个分页查询
     *
     * @param dataType   数据类型
     * @param options   分页查询设置对象
     *
     * @return 操作结果 DataAccessResult<IPagerModel<T>>
     */
    public <T> IPagerModel<T> findAllByPage(Class<?> dataType,@Nullable FindOptions options) throws DalFrameException {
        ITableInfo tableInfo = TableInfoBuilder.BuildTableInfoByAnnotation(dataType);
        DataAccessResult<IPagerModel<T>> result = findAllByPageOperate(dataType,tableInfo,options);
        if(!result.getSuccessFlag()){
            throw new DalFrameException(result.getCode(),result.getException().getMessage());
        }
        return result.getResult();
    }

    /**
     * 执行一个分页查询
     *
     * @param dataType 数据类型
     * @param options  分页查询设置对象
     *
     * @return 操作结果 DataAccessResult<IPagerModel<T>>
     */
    public <T> DataAccessResult<IPagerModel<T>> findAllByPageOperate(Class<?> dataType,ITableInfo tableInfo,
                                                                     @Nullable FindOptions options){
        if(options == null){
            options = FindOptions.defFindAllOptionsByPage();
        }

        DataAccessResult<IPagerModel<T>> result = new DataAccessResult<>(SqlKey.PAGESEARCH);
        SqlExpression sqlExpression = null;
        try {
            if(tableInfo == null){
                throw new DalFrameException(ErrorCode.NOT_FIND_TABLEINFO, ErrorMsg.TABLEINFO_NO_FIND_MSG);
            }
            IPagerModel pagerModel = new PagerModel(options.getPageIndex(), options.getPageSize());
            if(options.getRecordCountFlag()) {
                DataAccessResult<Long> countResult = countOperate(tableInfo, options.getConditionValueCollection());
                if (!countResult.getSuccessFlag()) {
                    throw new DalFrameException(countResult.getCode(),countResult.getException().getMessage());
                }
                pagerModel.setRecordCount(countResult.getResult());
            }
            BuilderContext context = BuilderContext.create(tableInfo, dataSource.getDataSourceTypeEnums(),
                    options.getConditionValueCollection(),pagerModel,options.getRefList(),options.getDbSortCollection());
            BaseSqlBuilder sqlBuilder = SqlBuilderFactory.create(SqlKey.PAGESEARCH, dataSource.getDataSourceTypeEnums());
            sqlExpression = sqlBuilder.run(context);
            BeanHandlerOptions beanHandlerOptions = new BeanHandlerOptions(tableInfo,sqlExpression.getHandlerColumnMapManage(),
                    sqlExpression.getDataSourceTypeEnums(),options.getJsonSer(), this.autoProcRuntime);
            beanHandlerOptions.merge(options.getBeanHandlerOptions());
            T list = (T) dataSource.executeQuery(sqlExpression.getFullSql(), sqlExpression.getParams(),
                    BeanListHandler.create(dataType,beanHandlerOptions));
            pagerModel.setDataList(list);
            result.setDone(pagerModel,sqlExpression);
        }catch (AutoProcRuntimeException autoProcRuntimeException){
            result.setError(ErrorCode.AUTOFILL_ERROR,autoProcRuntimeException, null);
        }catch (SqlBuilderException sqlException){
            result.setError(ErrorCode.SQL_BUILD_ERROR,sqlException, sqlExpression);
        }catch (SQLException sqlException){
            result.setError(ErrorCode.SQL_ERROR,sqlException, sqlExpression);
        }catch (DalFrameException e) {
            result.setError(e.getCode(),e, sqlExpression);
        }catch (Exception exception) {
            result.setError(ErrorCode.DAL_UNKNOWN_ERROR,exception, sqlExpression);
        }
        return result;
    }


    /**
     * 执行一个Count查询
     *
     * @param dataType                数据类型
     * @param conditionValueCollection 查询条件 可以为空或者null
     *
     * @return 操作结果 返回的条数
     */
    public DataAccessResult<Long> countOperate(Class<?> dataType, ConditionValueCollection conditionValueCollection) {
        ITableInfo tableInfo = TableInfoBuilder.BuildTableInfoByAnnotation(dataType);
        return countOperate(tableInfo,conditionValueCollection);
    }

    /**
     * 执行一个Count查询
     *
     * @param tableInfo                表信息
     * @param conditionValueCollection 查询条件 可以为空或者null
     * @return 操作结果 返回的条数
     */
    public DataAccessResult<Long> countOperate(ITableInfo tableInfo, ConditionValueCollection conditionValueCollection) {
        SqlKey key = SqlKey.COUNT;
        DataAccessResult<Long> result = new DataAccessResult<>(key);
        SqlExpression sqlExpression = null;
        try {
            List<String> refList = new ArrayList<>();
            refList.add(SysBaseEntity.BELONG_FULL_DATA);
            BuilderContext context = BuilderContext.create(tableInfo, dataSource.getDataSourceTypeEnums(),
                    conditionValueCollection,null, refList,null);
            BaseSqlBuilder sqlBuilder = SqlBuilderFactory.create(key, dataSource.getDataSourceTypeEnums());
            sqlExpression = sqlBuilder.run(context);
            Long count = dataSource.executeCount(sqlExpression.getFullSql(), sqlExpression.getParams());
            result.setDone(count, sqlExpression);
        }catch (AutoProcRuntimeException autoProcRuntimeException){
            result.setError(ErrorCode.AUTOFILL_ERROR,autoProcRuntimeException, null);
        }catch (SqlBuilderException sqlException){
            result.setError(ErrorCode.SQL_BUILD_ERROR,sqlException, sqlExpression);
        }catch (SQLException sqlException){
            result.setError(ErrorCode.SQL_ERROR,sqlException, sqlExpression);
        }catch (DalFrameException e) {
            result.setError(e.getCode(),e, sqlExpression);
        }catch (Exception exception) {
            result.setError(ErrorCode.DAL_UNKNOWN_ERROR,exception, sqlExpression);
        }
        return result;
    }


    /**
     * 查询指定类型的实体列表
     * @param dataType 被查询的数据类型
     *
     * @return DataAccessResult<List<T>>
     */
    public <T> T findAll(Class<?> dataType) throws DalFrameException {
        DataAccessResult<T> result = findAllOperate(dataType,null);
        if(!result.getSuccessFlag()){
            throw new DalFrameException(result.getCode(),result.getException().getMessage());
        }
        log.info("{}ms",result.getTotalDuration());
        return result.getResult();
    }

    /**
     * 查询指定类型的实体列表
     * @param dataType 被查询的数据类型
     * @param options 查询设定对象
     *
     * @return DataAccessResult<List<T>>
     */
    public <T> T findAll(Class<?> dataType,ITableInfo tableInfo,@Nullable FindOptions options) throws DalFrameException {
        DataAccessResult<T> result = findAllOperate(dataType,tableInfo,options);
        if(!result.getSuccessFlag()){
            throw new DalFrameException(result.getCode(),result.getException().getMessage());
        }
        log.info("{}ms",result.getTotalDuration());
        return result.getResult();
    }

    /**
     * 查询指定类型的实体列表
     * @param dataType 被查询的数据类型
     * @param options 查询设定对象
     *
     * @return DataAccessResult<List<T>>
     */
    public <T> T findAll(Class<?> dataType,@Nullable FindOptions options) throws DalFrameException {
        DataAccessResult<T> result = findAllOperate(dataType,options);
        if(!result.getSuccessFlag()){
            throw new DalFrameException(result.getCode(),result.getException().getMessage());
        }
        log.info("{}ms",result.getTotalDuration());
        return result.getResult();
    }
    /**
     * 查询指定类型的实体列表
     * @param tableInfo 表结构
     * @param options 查询设定对象
     *
     * @return DataAccessResult<List<T>>
     */
    public <T> T findAll(ITableInfo tableInfo,@Nullable FindOptions options) throws DalFrameException {
        DataAccessResult<T> result = findAllOperate(XDynamicModel.class,tableInfo,options);
        if(!result.getSuccessFlag()){
            throw new DalFrameException(result.getCode(),result.getException().getMessage());
        }
        log.info("{}ms",result.getTotalDuration());
        return (T) result.getResult();
    }

    /**
     * 查询指定类型的实体列表
     * @param dataType 数据类型
     * @param options 查询设定对象
     *
     * @return DataAccessResult<List<T>>
     */
    public <T> DataAccessResult<T> findAllOperate(Class<?> dataType,@Nullable FindOptions options) {
        ITableInfo tableInfo = TableInfoBuilder.BuildTableInfoByAnnotation(dataType);
        return findAllOperate(dataType,tableInfo,options);
    }
    /**
     * 查询指定类型的实体列表
     * @param dataType 被查询的数据类型
     * @param tableInfo 表结构
     * @param options 查询设定对象
     *
     * @return DataAccessResult<T>
     */
    public <T> DataAccessResult<T> findAllOperate(Class<?> dataType,ITableInfo tableInfo, @Nullable FindOptions options) {

        if(options == null){
            options = FindOptions.defFindAllOptions();
        }
        DataAccessResult<T> result = new DataAccessResult<>(SqlKey.SEARCH);
        SqlExpression sqlExpression = null;
        try {
            BuilderContext context = BuilderContext.create(tableInfo, dataSource.getDataSourceTypeEnums(),options.getConditionValueCollection(),
                    null,options.getRefList(),options.getDbSortCollection());
            BaseSqlBuilder sqlBuilder = SqlBuilderFactory.create(SqlKey.SEARCH, dataSource.getDataSourceTypeEnums());
            sqlExpression = sqlBuilder.run(context);

            BeanHandlerOptions beanHandlerOptions = new BeanHandlerOptions(tableInfo,sqlExpression.getHandlerColumnMapManage(),
                    sqlExpression.getDataSourceTypeEnums(),options.getJsonSer(), this.autoProcRuntime);
            beanHandlerOptions.merge(options.getBeanHandlerOptions());

            T list = (T) dataSource.executeQuery(sqlExpression.getFullSql(),
                    sqlExpression.getParams(),BeanListHandler.create(dataType,beanHandlerOptions));
            result.setDone(list,sqlExpression);
        }catch (AutoProcRuntimeException autoProcRuntimeException){
            result.setError(ErrorCode.AUTOFILL_ERROR,autoProcRuntimeException, null);
        }catch (SqlBuilderException sqlException){
            result.setError(ErrorCode.SQL_BUILD_ERROR,sqlException, sqlExpression);
        }catch (SQLException sqlException){
            result.setError(ErrorCode.SQL_ERROR,sqlException, sqlExpression);
        }catch (DalFrameException e) {
            result.setError(e.getCode(),e, sqlExpression);
        }catch (Exception exception) {
            result.setError(ErrorCode.DAL_UNKNOWN_ERROR,exception, sqlExpression);
        }
        return result;

    }


    /**
     * 数据记录是否存在 根据PK进行判断
     * @param data 数据
     *
     * @return DataAccessResult
     */
    public Boolean isExistsByPk(Object data) throws DalFrameException {
        DataAccessResult<Boolean> dataAccessResult = isExistsByPkOperate(data.getClass(),data);
        if(!dataAccessResult.getSuccessFlag()){
            throw new DalFrameException(dataAccessResult.getCode(),dataAccessResult.getException().getMessage());
        }
        return dataAccessResult.getResult();
    }
    /**
     * 数据记录是否存在 根据AK进行判断
     * @param data 数据
     *
     * @return DataAccessResult
     */
    public Boolean isExists(Object data) throws DalFrameException {
        DataAccessResult<Boolean> dataAccessResult = isExistsOperate(data.getClass(),data);
        if(!dataAccessResult.getSuccessFlag()){
            throw new DalFrameException(dataAccessResult.getCode(),dataAccessResult.getException().getMessage());
        }
        return dataAccessResult.getResult();
    }
    /**
     * 数据记录是否存在 根据AK进行判断
     * @param data 数据
     * @param tableInfo 数据表结构
     *
     * @return DataAccessResult
     */
    public Boolean isExists(Object data,ITableInfo tableInfo) throws DalFrameException {
        DataAccessResult<Boolean> dataAccessResult = isExistsOperate(data,tableInfo);
        if(!dataAccessResult.getSuccessFlag()){
            throw new DalFrameException(dataAccessResult.getCode(),dataAccessResult.getException().getMessage());
        }
        return dataAccessResult.getResult();
    }

    /**
     * 数据记录是否存在 根据AK进行判断
     * @param dataRow 数据
     * @param tableInfo 数据表结构
     *
     * @return DataAccessResult
     */
    public DataAccessResult<Boolean> isExistsOperate(Object dataRow,ITableInfo tableInfo) {
        DataAccessResult<Boolean> result = new DataAccessResult<>(SqlKey.EXISTS);
        SqlExpression sqlExpression = null;
        try {
            BuilderContext context = BuilderContext.create(tableInfo, dataSource.getDataSourceTypeEnums(), dataRow);
            BaseSqlBuilder sqlBuilder = SqlBuilderFactory.create(SqlKey.EXISTS, dataSource.getDataSourceTypeEnums());
            sqlExpression = sqlBuilder.run(context);
            Long count = dataSource.executeCount(sqlExpression.getFullSql(), sqlExpression.getParams());
            result.setDone(count > 0, sqlExpression);
        }catch (AutoProcRuntimeException autoProcRuntimeException){
            result.setError(ErrorCode.AUTOFILL_ERROR,autoProcRuntimeException, null);
        }catch (SqlBuilderException sqlException){
            result.setError(ErrorCode.SQL_BUILD_ERROR,sqlException, sqlExpression);
        }catch (SQLException sqlException){
            result.setError(ErrorCode.SQL_ERROR,sqlException, sqlExpression);
        }catch (DalFrameException e) {
            result.setError(e.getCode(),e, sqlExpression);
        }catch (Exception exception) {
            result.setError(ErrorCode.DAL_UNKNOWN_ERROR,exception, sqlExpression);
        }
        return result;
    }


    /**
     * 数据记录是否存在 根据AK进行判断
     * @param dataType 数据类型
     * @param dataRow dataRow
     *
     * @return DataAccessResult
     */
    public DataAccessResult<Boolean> isExistsOperate(Class<?> dataType,Object dataRow) {
        ITableInfo tableInfo = TableInfoBuilder.BuildTableInfoByAnnotation(dataType);
        return isExistsOperate(dataRow,tableInfo);
    }


    /**
     * 数据记录是否存在 根据AK进行判断
     * @param obj 判断的对象
     *
     * @return DataAccessResult
     */
    public DataAccessResult<Boolean> isExistsByPkOperate(Class<?> dataType,Object obj) {
        DataAccessResult<Boolean> result = new DataAccessResult<>(SqlKey.EXISTS);
        SqlExpression sqlExpression = null;
        try {
            ITableInfo tableInfo = TableInfoBuilder.BuildTableInfoByAnnotation(dataType);
            BuilderContext context = BuilderContext.create(tableInfo, dataSource.getDataSourceTypeEnums(), obj);
            BaseSqlBuilder sqlBuilder = SqlBuilderFactory.create(SqlKey.EXISTS_BY_KEY, dataSource.getDataSourceTypeEnums());
            sqlExpression = sqlBuilder.run(context);
            Long count = dataSource.executeCount(sqlExpression.getFullSql(), sqlExpression.getParams());
            result.setDone(count > 0, sqlExpression);
        }catch (AutoProcRuntimeException autoProcRuntimeException){
            result.setError(ErrorCode.AUTOFILL_ERROR,autoProcRuntimeException, null);
        }catch (SqlBuilderException sqlException){
            result.setError(ErrorCode.SQL_BUILD_ERROR,sqlException, sqlExpression);
        }catch (SQLException sqlException){
            result.setError(ErrorCode.SQL_ERROR,sqlException, sqlExpression);
        }catch (DalFrameException e) {
            result.setError(e.getCode(),e, sqlExpression);
        }catch (Exception exception) {
            result.setError(ErrorCode.DAL_UNKNOWN_ERROR,exception, sqlExpression);
        }
        return result;
    }
    /************* 是否存在操作 ***************/




    public <E> Integer batchCreate(Class<?> dataType,Collection<E> collection) throws DalFrameException {
        DataAccessResult<Integer> result = batchCreateOperate(dataType,collection);
        if(!result.getSuccessFlag()){
            throw new DalFrameException(result.getCode(),result.getException().getMessage());
        }
        return result.getResult();
    }

    /**
     * 批量添加数据时，进行分批操作
     *
     * @param dataType 数据类型
     * @param collection 备操作的集合
     * @param maxDataLength 最大的数据条数
     *
     * @return 受影响的行数
     * @throws DalFrameException 异常
     */
    public <E> Integer batchCreate(Class<?> dataType, Collection<E> collection, Integer maxDataLength) throws DalFrameException {
        if(dataType == null){
            throw new DalFrameException(ErrorCode.CLASS_TYPE_NULL, ErrorMsg.CLASS_TYPE_NULL_MSG);
        }
        if(collection == null){
            throw new DalFrameException(ErrorCode.ARGS_ERROR, ErrorMsg.ARGS_ERROR_MSG);
        }
        if(maxDataLength == null){
            maxDataLength = 1000;
        }
        if (maxDataLength < 1) {
            maxDataLength = 1000;
        }
        int collectionSize = collection.size();
        if (collectionSize <= maxDataLength) {
            return this.batchCreate(dataType, collection);
        }
        int beginIndex = collectionSize / maxDataLength;
        int remainingCollectionCount = collectionSize % maxDataLength;

        if (remainingCollectionCount > 0) {
            beginIndex++;
        }
        Collection<E> tempCollection = new ArrayList<>(maxDataLength);
        int loopCount = 1;
        int loopIndex = maxDataLength;

        DataAccessResult<Integer> result = new DataAccessResult<>(SqlKey.MANY_INSERT);

        while (loopCount <= beginIndex) {
            //当原集合拆分后有余量时，则最后一次特殊时只循环余量的数据
            if (remainingCollectionCount > 0 && loopCount == beginIndex) {
                loopIndex = remainingCollectionCount;
            }
            tempCollection.clear();
            for (int i = 0; i < loopIndex; i++) {
                tempCollection.add(CollectionUtils.get(collection, (loopCount - 1) * maxDataLength + i));
            }
            result = batchCreateOperate(dataType, tempCollection);
            if (!result.getSuccessFlag()) {
                throw new DalFrameException(result.getCode(),result.getException().getMessage());
            }
            loopCount++;
        }
        return result.getResult();
    }
    /**
     * 批量插入
     * @param dataType 数据类型
     * @param collection 列表集合
     *
     * @return DataAccessResult
     */
    public <E> DataAccessResult<Integer> batchCreateOperate(Class<?> dataType,Collection<E> collection){
        ITableInfo tableInfo = TableInfoBuilder.BuildTableInfoByAnnotation(dataType);
        return batchCreateOperate(collection,tableInfo);
    }

    /**
     * 批量插入
     * @param tableInfo 表结果
     * @param collection 列表集合
     *
     * @return DataAccessResult
     */
    public <E> DataAccessResult<Integer> batchCreateOperate(Collection<E> collection,ITableInfo tableInfo){
        DataAccessResult<Integer> result = new DataAccessResult<>(SqlKey.MANY_INSERT);
        SqlExpression sqlExpression = null;
        try {
            if(CollectionUtil.isEmpty(collection)){
                result.setDone(0, sqlExpression);
                return result;
            }
            autoProcRuntime.autoFill(collection,tableInfo, RunOpportunity.C);
            BuilderContext context = BuilderContext.create(tableInfo, dataSource.getDataSourceTypeEnums(), collection);
            BaseSqlBuilder sqlBuilder = SqlBuilderFactory.create(SqlKey.MANY_INSERT, dataSource.getDataSourceTypeEnums());
            sqlExpression = sqlBuilder.run(context);
            Integer count = dataSource.executeUpdate(sqlExpression.getFullSql(), sqlExpression.getParams());
            result.setDone(count, sqlExpression);
        }catch (AutoProcRuntimeException autoProcRuntimeException){
            result.setError(ErrorCode.AUTOFILL_ERROR,autoProcRuntimeException, null);
        }catch (SqlBuilderException sqlException){
            result.setError(ErrorCode.SQL_BUILD_ERROR,sqlException, sqlExpression);
        }catch (SQLException sqlException) {
            result.setError(ErrorCode.SQL_ERROR, sqlException, sqlExpression);
        }catch (Exception exception) {
            result.setError(ErrorCode.DAL_UNKNOWN_ERROR,exception, sqlExpression);
        }
        return result;
    }


    /**
     * 插入一条新记录
     * @param model 数据记录
     * @param tableInfo 表结构
     *
     * @return DataAccessResult
     */
    public Integer createNew(Object model,ITableInfo tableInfo) throws DalFrameException {
        DataAccessResult<Integer> result = createNewOperate(model,tableInfo);
        if(!result.getSuccessFlag()){
            throw new DalFrameException(result.getCode(),result.getException().getMessage());
        }
        return result.getResult();
    }

    /**
     * 插入一条新记录
     * @param model 数据记录
     *
     * @return DataAccessResult
     */
    public Integer createNew(Object model) throws DalFrameException {
        DataAccessResult<Integer> result = createNewOperate(model,model.getClass());
        if(!result.getSuccessFlag()){
            throw new DalFrameException(result.getCode(),result.getException().getMessage());
        }
        return result.getResult();
    }

    /**
     * 插入一条新记录
     * @param dataRow 数据记录
     * @param dataType 数据类型
     * @return DataAccessResult
     */
    public DataAccessResult<Integer> createNew(Object dataRow, Class<?> dataType) {
        return createNewOperate(dataRow,dataType);
    }


    /**
     * 插入一条新记录
     * @param dataRow 数据记录
     * @param dataType 数据类型
     * @return DataAccessResult
     */
    public DataAccessResult<Integer> createNewOperate(Object dataRow, Class<?> dataType) {
        ITableInfo tableInfo = TableInfoBuilder.BuildTableInfoByAnnotation(dataType);
        return createNewOperate(dataRow,tableInfo);
    }


    /**
     * 插入一条新记录
     * @param dataRow 数据记录
     * @param tableInfo 表结构
     *
     * @return DataAccessResult
     */
    public DataAccessResult<Integer> createNewOperate(Object dataRow, ITableInfo tableInfo) {
        DataAccessResult<Integer> result = new DataAccessResult<>(SqlKey.INSERT);
        SqlExpression sqlExpression = null;
        try {
            autoProcRuntime.autoFill(dataRow,tableInfo, RunOpportunity.C);
            BuilderContext context = BuilderContext.create(tableInfo, dataSource.getDataSourceTypeEnums(), dataRow);
            BaseSqlBuilder sqlBuilder = SqlBuilderFactory.create(SqlKey.INSERT, dataSource.getDataSourceTypeEnums());
            sqlExpression = sqlBuilder.run(context);
            Integer count = dataSource.executeUpdate(sqlExpression.getFullSql(), sqlExpression.getParams());
            result.setDone(count, sqlExpression);
        }catch (AutoProcRuntimeException autoProcRuntimeException){
            result.setError(ErrorCode.AUTOFILL_ERROR,autoProcRuntimeException, null);
        }catch (SqlBuilderException sqlException){
            result.setError(ErrorCode.SQL_BUILD_ERROR,sqlException, sqlExpression);
        }catch (SQLException sqlException){
            result.setError(ErrorCode.SQL_ERROR,sqlException, sqlExpression);
        }catch (Exception exception) {
            result.setError(ErrorCode.DAL_UNKNOWN_ERROR,exception, sqlExpression);
        }
        return result;
    }



    /**
     * 删除一条新记录
     * @param dataRow 数据记录
     *
     * @return 数据受影响的行数
     */
    public Integer delete(Object dataRow) throws DalFrameException {

        return delete(dataRow,dataRow.getClass());
    }
    /**
     * 删除一条新记录
     * @param dataRow 数据记录
     * @param dataType 对象类型
     *
     * @return 数据受影响的行数
     */
    public Integer delete(Object dataRow,Class<?> dataType) throws DalFrameException {
        ITableInfo tableInfo = TableInfoBuilder.BuildTableInfoByAnnotation(dataType);
        DataAccessResult<Integer> result = deleteOperate(dataRow,tableInfo);
        if(!result.getSuccessFlag()){
            throw new DalFrameException(result.getCode(),result.getException().getMessage());
        }
        return result.getResult();
    }

    /**
     * 删除一条新记录
     * @param dataRow 数据记录
     * @param tableInfo 数据类型
     *
     * @return 数据受影响的行数
     */
    public Integer delete(Object dataRow,ITableInfo tableInfo) throws DalFrameException {
        DataAccessResult<Integer> result = deleteOperate(dataRow,tableInfo);
        if(!result.getSuccessFlag()){
            throw new DalFrameException(result.getCode(),result.getException().getMessage());
        }
        return result.getResult();
    }




    /**
     * 删除一条新记录
     * @param dataRow 数据记录
     * @param tableInfo 数据结构
     *
     * @return DataAccessResult
     */
    public DataAccessResult<Integer> deleteOperate(Object dataRow, ITableInfo tableInfo) {
        if(tableInfo == null){
            throw new DalFrameException(ErrorCode.TABLEINFO_NO_FIND,"tableInfo不能为空,或者缺失列信息");
        }
        DataAccessResult<Integer> result = new DataAccessResult<>(SqlKey.DELETE);
        SqlExpression sqlExpression = null;
        try {
            BuilderContext context = BuilderContext.create(tableInfo, dataSource.getDataSourceTypeEnums(), dataRow);
            BaseSqlBuilder sqlBuilder = SqlBuilderFactory.create(SqlKey.DELETE, dataSource.getDataSourceTypeEnums());
            sqlExpression = sqlBuilder.run(context);
            Integer count = dataSource.executeUpdate(sqlExpression.getFullSql(), sqlExpression.getParams());
            result.setDone(count, sqlExpression);
        }catch (AutoProcRuntimeException autoProcRuntimeException){
            result.setError(ErrorCode.AUTOFILL_ERROR,autoProcRuntimeException, null);
        }catch (SqlBuilderException sqlException){
            result.setError(ErrorCode.SQL_BUILD_ERROR,sqlException, sqlExpression);
        }catch (SQLException sqlException){
            result.setError(ErrorCode.SQL_ERROR,sqlException, sqlExpression);
        }catch (Exception exception) {
            result.setError(ErrorCode.DAL_UNKNOWN_ERROR,exception, sqlExpression);
        }
        return result;
    }



    /**
     * 根据primary key 更新
     *
     * @param dataRow   数据记录
     *
     * @return 数据库受影响的对象
     */
    public Integer update(Object dataRow) throws DalFrameException {
        DataAccessResult<Integer> result = updateOperate(dataRow,
                TableInfoBuilder.BuildTableInfoByAnnotation(dataRow.getClass()),true);
        if(!result.getSuccessFlag()){
            throw new DalFrameException(result.getCode(),result.getException().getMessage());
        }
        return result.getResult();
    }

    /**
     * 根据primary key 更新
     *
     * @param dataRow   数据记录
     * @param updateAttr 修改的列和条件
     * @return 数据库受影响的对象
     */
    public Integer update(Object dataRow,UpdateAttr updateAttr) throws DalFrameException {
        DataAccessResult<Integer> result = updateOperate(dataRow,
                TableInfoBuilder.BuildTableInfoByAnnotation(dataRow.getClass()),updateAttr,true);
        if(!result.getSuccessFlag()){
            throw new DalFrameException(result.getCode(),result.getException().getMessage());
        }
        return result.getResult();
    }

    /**
     * 根据primary key 更新
     *
     * @param dataRow   数据记录
     * @param noCountExceptionThrown 如果没有行数被影响是否抛出异常
     *
     * @return 数据库受影响的对象
     */
    public Integer update(Object dataRow, ITableInfo tableInfo,boolean noCountExceptionThrown) throws DalFrameException {
        DataAccessResult<Integer> result = updateOperate(dataRow,tableInfo,noCountExceptionThrown);
        if(!result.getSuccessFlag()){
            throw new DalFrameException(result.getCode(),result.getException().getMessage());
        }
        return result.getResult();
    }

    /**
     * 根据primary key 更新
     *
     * @param dataRow   数据记录
     * @param tableInfo 表结构
     * @param updateAttr 修改条件和结构
     * @param noCountExceptionThrown 如果没有行数被影响是否抛出异常
     *
     * @return 数据库受影响的对象
     */
    public Integer update(Object dataRow,ITableInfo tableInfo,UpdateAttr updateAttr,boolean noCountExceptionThrown) throws DalFrameException {
        DataAccessResult<Integer> result = updateOperate(dataRow,tableInfo,updateAttr,noCountExceptionThrown);
        if(!result.getSuccessFlag()){
            throw new DalFrameException(result.getCode(),result.getException().getMessage());
        }
        return result.getResult();
    }

    /**
     * 根据primary key 更新
     *
     * @param dataRow   数据记录
     * @param tableInfo 数据结构
     * @param noCountExceptionThrown 如果没有行数被影响是否抛出异常
     *
     * @return 操作结果
     */
    public DataAccessResult<Integer> updateOperate(Object dataRow, ITableInfo tableInfo, boolean noCountExceptionThrown) {
        return updateOperate(dataRow,tableInfo,null,noCountExceptionThrown);
    }
    /**
     * 根据primary key 更新
     *
     * @param dataRow   数据记录
     * @param tableInfo 数据结构
     * @param noCountExceptionThrown 如果没有行数被影响是否抛出异常
     *
     * @return 操作结果
     */
    public DataAccessResult<Integer> updateOperate(Object dataRow, ITableInfo tableInfo,UpdateAttr updateAttr,
                                                   boolean noCountExceptionThrown) {
        DataAccessResult<Integer> result = new DataAccessResult<>(SqlKey.UPDATE);
        SqlExpression sqlExpression = null;
        try {
            if(updateAttr == null){
                updateAttr = new UpdateAttr(UpdateWhereMode.PK,noCountExceptionThrown);
            }
            BuilderContext context = BuilderContext.create(tableInfo, dataSource.getDataSourceTypeEnums(), dataRow,updateAttr);
            BaseSqlBuilder sqlBuilder = SqlBuilderFactory.create(SqlKey.UPDATE, dataSource.getDataSourceTypeEnums());
            sqlExpression = sqlBuilder.run(context);
            int count = dataSource.executeUpdate(sqlExpression.getFullSql(), sqlExpression.getParams());
            if(count == 0 && noCountExceptionThrown){
                throw  new DalFrameException(ErrorCode.UPDATE_CONFLICT,tableInfo.getName() + "更新失败,没有任何的数据被影响");
            }
            result.setDone(count, sqlExpression);
        }catch (AutoProcRuntimeException autoProcRuntimeException){
            result.setError(ErrorCode.AUTOFILL_ERROR,autoProcRuntimeException, null);
        }catch (SqlBuilderException sqlException){
            result.setError(ErrorCode.SQL_BUILD_ERROR,sqlException, sqlExpression);
        }catch (SQLException sqlException){
            result.setError(ErrorCode.SQL_ERROR,sqlException, sqlExpression);
        }catch (Exception exception) {
            result.setError(ErrorCode.DAL_UNKNOWN_ERROR,exception, sqlExpression);
        }
        return result;
    }

    /**
     * 根据primary key 更新
     *
     * @param dataRow   数据记录
     * @param dataType 数据类型
     * @param noCountExceptionThrown 如果没有行数被影响是否抛出异常
     *
     * @return 操作结果
     */
    public DataAccessResult<Integer> updateOperate(Object dataRow, Class<?> dataType,boolean noCountExceptionThrown) {
        ITableInfo tableInfo = TableInfoBuilder.BuildTableInfoByAnnotation(dataType);
        return updateOperate(dataRow,tableInfo,noCountExceptionThrown);
    }

    /**
     * 根据指定条件来执行 批量UPDATE语句
     *
     * @param tableInfo 表结构
     * @param setWrapCollection set子句集合
     * @param whereCollection where子句集合
     *
     * @return 数据库操作受影响的行数
     */
    public Integer updateMany(ITableInfo tableInfo,
                              SetWrapCollection setWrapCollection,ConditionValueCollection whereCollection) throws DalFrameException {
        DataAccessResult<Integer> result = updateManyOperate(tableInfo,setWrapCollection,whereCollection,false);
        if(!result.getSuccessFlag()){
            throw new DalFrameException(result.getCode(),result.getException().getMessage());
        }
        return result.getResult();
    }


    /**
     * 根据指定条件来执行 批量UPDATE语句
     *
     * @param tableInfo 表结构
     * @param setWrapCollection set子句集合
     * @param whereCollection where子句集合
     * @param noCountExceptionThrown 如果没有行数被影响是否抛出异常
     *
     * @return 数据库操作受影响的行数
     */
    public Integer updateMany(ITableInfo tableInfo,
                              SetWrapCollection setWrapCollection,ConditionValueCollection whereCollection,
                              boolean noCountExceptionThrown) throws DalFrameException {
        DataAccessResult<Integer> result = updateManyOperate(tableInfo,setWrapCollection,whereCollection,noCountExceptionThrown);
        if(!result.getSuccessFlag()){
            throw new DalFrameException(result.getCode(),result.getException().getMessage());
        }
        return result.getResult();

    }

    /**
     * 根据指定条件来执行 批量UPDATE语句
     *
     * @param tableInfo 表结构
     * @param setWrapCollection set子句集合
     * @param whereCollection where子句集合
     * @param noCountExceptionThrown 如果没有行数被影响是否抛出异常
     *
     * @return 数据库操作受影响的行数
     */
    public DataAccessResult<Integer> updateManyOperate(ITableInfo tableInfo,
                                                       SetWrapCollection setWrapCollection,ConditionValueCollection whereCollection,
                                                       boolean noCountExceptionThrown) {
        DataAccessResult<Integer> result = new DataAccessResult<>(SqlKey.UPDATE_MANY);
        SqlExpression sqlExpression = null;
        try {
            BuilderContext context = BuilderContext.create(tableInfo, dataSource.getDataSourceTypeEnums(), whereCollection,setWrapCollection);
            BaseSqlBuilder sqlBuilder = SqlBuilderFactory.create(SqlKey.UPDATE_MANY, dataSource.getDataSourceTypeEnums());
            sqlExpression = sqlBuilder.run(context);
            int count = dataSource.executeUpdate(sqlExpression.getFullSql(), sqlExpression.getParams());
            if(count == 0 && noCountExceptionThrown){
                throw new DalFrameException(ErrorCode.UPDATE_CONFLICT,tableInfo.getName() + "更新失败,没有任何的数据被影响");
            }
            result.setDone(count, sqlExpression);
        }catch (AutoProcRuntimeException autoProcRuntimeException){
            result.setError(ErrorCode.AUTOFILL_ERROR,autoProcRuntimeException, null);
        }catch (SqlBuilderException sqlException){
            result.setError(ErrorCode.SQL_BUILD_ERROR,sqlException, sqlExpression);
        }catch (SQLException sqlException){
            result.setError(ErrorCode.SQL_ERROR,sqlException, sqlExpression);
        }catch (Exception exception) {
            result.setError(ErrorCode.DAL_UNKNOWN_ERROR,exception, sqlExpression);
        }
        return result;
    }





    /**
     * 根据指定条件来执行 批量DELETE语句
     *
     * @param tableInfo 表结构
     * @param whereCollection where子句集合
     *
     * @return 数据库操作受影响的行数
     */
    public Integer deleteMany(ITableInfo tableInfo,ConditionValueCollection whereCollection) throws DalFrameException {
        DataAccessResult<Integer> result = deleteManyOperate(tableInfo,whereCollection);
        if(!result.getSuccessFlag()){
            throw new DalFrameException(result.getCode(),result.getException().getMessage());
        }
        return result.getResult();
    }

    /**
     * 根据指定条件来执行 批量DELETE语句
     *
     * @param tableInfo 表结构
     * @param whereCollection where子句集合
     *
     * @return 数据库操作受影响的行数
     */
    public DataAccessResult<Integer> deleteManyOperate(ITableInfo tableInfo,
                                                       ConditionValueCollection whereCollection
                                                       ) {
        DataAccessResult<Integer> result = new DataAccessResult<>(SqlKey.DELETE_MANY);
        SqlExpression sqlExpression = null;
        try {
            BuilderContext context = BuilderContext.create(tableInfo, dataSource.getDataSourceTypeEnums(),
                    whereCollection,new SetWrapCollection());
            BaseSqlBuilder sqlBuilder = SqlBuilderFactory.create(SqlKey.DELETE_MANY, dataSource.getDataSourceTypeEnums());
            sqlExpression = sqlBuilder.run(context);
            Integer count = dataSource.executeUpdate(sqlExpression.getFullSql(), sqlExpression.getParams());
            result.setDone(count, sqlExpression);
        }catch (AutoProcRuntimeException autoProcRuntimeException){
            result.setError(ErrorCode.AUTOFILL_ERROR,autoProcRuntimeException, null);
        }catch (SqlBuilderException sqlException){
            result.setError(ErrorCode.SQL_BUILD_ERROR,sqlException, sqlExpression);
        }catch (SQLException sqlException){
            result.setError(ErrorCode.SQL_ERROR,sqlException, sqlExpression);
        }catch (Exception exception) {
            result.setError(ErrorCode.DAL_UNKNOWN_ERROR,exception, sqlExpression);
        }
        return result;
    }

    /**
     * 测试连接
     *
     * @return 当前时间
     */
    public Object testConnect() throws DalFrameException{
        try {
            return this.getDataSource().testConnect();
        }catch (SQLException sqlException){
            throw new DalFrameException(ErrorCode.SQL_ERROR,sqlException.getMessage());
        }
    }


    /**
     * 开启一个事务,如果当前线程中存在事务 则加入到当前事务中
     * 否则创建一个新的事务
     *
     * @return 返回一个事务对象
     */
    public IDbTransaction beginTransaction(){
        IDbTransaction transaction;
        if(DbTransactionContext.hasDbTransaction()){
            transaction = DbTransactionContext.getTrans();
        }else {
            transaction = dataSource.beginTransaction();
            DbTransactionContext.addTransaction(transaction);
        }
        return transaction;
    }

    /**
     * 开启一个事务,如果当前线程中存在事务 则加入到当前事务中
     * 否则创建一个新的事务
     * @param level 事务隔离级别
     * @return 返回一个事务对象
     */
    public IDbTransaction beginTransaction(int level){
        IDbTransaction transaction;
        if(DbTransactionContext.hasDbTransaction()){
            transaction = DbTransactionContext.getTrans();
        }else {
            transaction = dataSource.beginTransaction(level);
            DbTransactionContext.addTransaction(transaction);
        }
        return transaction;
    }
    /**
     * 提交一个事务
     */
    public void commitTran(){
        dataSource.commitTran();
    }
    /**
     * 回滚事务
     */
    public void rollBackTran(){
        dataSource.rollBackTran();
    }
    /**
     * 创建或者新增(根据主键)
     *
     * @param model 保存的对象
     *
     * @return 操作结果
     */
    public Integer createOrUpdate(Object model){
        return createOrUpdate(model,model.getClass());
    }

    /**
     * 创建或者新增(根据主键)
     *
     * @param model 保存的对象
     * @param dataType 数据类型
     *
     * @return 操作结果
     */
    public Integer createOrUpdate(Object model,Class<?> dataType){
        ITableInfo tableInfo = TableInfoBuilder.BuildTableInfoByAnnotation(dataType);
        return createOrUpdate(model,tableInfo);
    }

    /**
     * 创建或者新增(根据主键)
     *
     * @param model 保存的对象
     * @param tableInfo 表结构
     *
     * @return 操作结果
     */
    public Integer createOrUpdate(Object model,ITableInfo tableInfo){
        if(model == null){
            return 0;
        }
        if(tableInfo == null){
            throw new DalFrameException(ErrorCode.TABLEINFO_NO_FIND,"tableInfo不能为空,或者缺失列信息");
        }
        ArrayList arrayList = new ArrayList();
        arrayList.add(model);
        DataAccessResult<Integer> result = batchSaveOperate(tableInfo, arrayList);
        if (!result.getSuccessFlag()) {
            throw new DalFrameException(result.getCode(),result.getException().getMessage());
        }
        return result.getResult();
    }


    /**
     * 批量保存(存在则修改)
     *
     * @param tableInfo 表结构
     * @param collection 被操作的结果
     * @param <E>
     * @return 操作结果
     * @throws DalFrameException 异常
     */
    public <E> Integer batchSave(ITableInfo tableInfo, Collection<E> collection) throws DalFrameException {
        DataAccessResult<Integer> result = batchSaveOperate(tableInfo, collection);
        if (!result.getSuccessFlag()) {
            throw new DalFrameException(result.getCode(),result.getException().getMessage());
        }
        return result.getResult();
    }
    /**
     * 批量保存(存在则修改)
     *
     * @param dataType 数据类型
     * @param collection 被操作的结果
     *
     * @param <E>
     * @return 操作结果
     * @throws DalFrameException 异常
     */
    public <E> Integer batchSave(Class<?> dataType, Collection<E> collection) throws DalFrameException {
        DataAccessResult<Integer> result = batchSaveOperate(dataType, collection);
        if (!result.getSuccessFlag()) {
            throw new DalFrameException(result.getCode(),result.getException().getMessage());
        }
        return result.getResult();
    }

    /**
     * 批量保存数据时，进行分批操作
     *
     * @param dataType 数据类型
     * @param collection 被操作的集合
     * @param maxDataLength 单次的最大行数
     *
     * @return 操作结果
     * @throws DalFrameException
     */
    public <E> Integer batchSave(Class<?> dataType, Collection<E> collection, Integer maxDataLength) throws DalFrameException {

        if (maxDataLength < 1) {
            maxDataLength = 100;
        }
        int collectionSize = collection.size();
        if (collectionSize <= maxDataLength) {
            return this.batchSave(dataType, collection);
        }

        int beginIndex = collectionSize / maxDataLength;
        int remainingCollectionCount = collectionSize % maxDataLength;

        if (remainingCollectionCount > 0) {
            beginIndex++;
        }
        Collection<E> tempCollection = new ArrayList<>(maxDataLength);
        int loopCount = 1;
        int loopIndex = maxDataLength;

        DataAccessResult<Integer> result = new DataAccessResult<>(SqlKey.BATCH_SAVE);

        while (loopCount <= beginIndex) {
            //当原集合拆分后有余量时，则最后一次特殊时只循环余量的数据
            if (remainingCollectionCount > 0 && loopCount == beginIndex) {
                loopIndex = remainingCollectionCount;
            }
            tempCollection.clear();
            for (int i = 0; i < loopIndex; i++) {
                // log.info("loop:{} max:{} ci:{}", loopCount, maxDataLength, (loopCount - 1) * maxDataLength + i);
                tempCollection.add(CollectionUtils.get(collection, (loopCount - 1) * maxDataLength + i));
            }

            result = batchCreateOperate(dataType, tempCollection);
            if (!result.getSuccessFlag()) {
                throw new DalFrameException(result.getCode(),result.getException().getMessage());
            }

            loopCount++;
        }


        return result.getResult();
    }

    /**
     * 批量保存 存在则UPDATE
     *
     * @param dataType   数据类型
     * @param collection 列表集合
     * @return DataAccessResult
     */
    public <E> DataAccessResult<Integer> batchSaveOperate(Class<?> dataType, Collection<E> collection) {
        ITableInfo tableInfo = TableInfoBuilder.BuildTableInfoByAnnotation(dataType);
        return batchSaveOperate(tableInfo,collection);
    }


    /**
     * 批量保存 存在则UPDATE
     *
     * @param tableInfo  表结构
     * @param collection 列表集合
     * @return DataAccessResult
     */
    public <E> DataAccessResult<Integer> batchSaveOperate(ITableInfo tableInfo, Collection<E> collection) {
        DataAccessResult<Integer> result = new DataAccessResult<>(SqlKey.BATCH_SAVE);
        SqlExpression sqlExpression = null;
        if(collection == null || collection.isEmpty()){
            result.setDone(0, sqlExpression);
            return result;
        }
        try {
            autoProcRuntime.autoFill(collection, tableInfo, RunOpportunity.C);
            BuilderContext context = BuilderContext.create(tableInfo, dataSource.getDataSourceTypeEnums(), collection);
            BaseSqlBuilder sqlBuilder = SqlBuilderFactory.create(SqlKey.BATCH_SAVE, dataSource.getDataSourceTypeEnums());
            sqlExpression = sqlBuilder.run(context);
            int[] count = dataSource.executeBatch(sqlExpression.getFullSql(), sqlExpression.getParams());
            int effectCount = collection.size();
            result.setDone(effectCount, sqlExpression);
        }catch (AutoProcRuntimeException autoProcRuntimeException){
            result.setError(ErrorCode.AUTOFILL_ERROR,autoProcRuntimeException, null);
        }catch (SqlBuilderException sqlException){
            result.setError(ErrorCode.SQL_BUILD_ERROR,sqlException, sqlExpression);
        }catch (SQLException sqlException){
            result.setError(ErrorCode.SQL_ERROR,sqlException, sqlExpression);
        }catch (Exception exception) {
            result.setError(ErrorCode.DAL_UNKNOWN_ERROR,exception, sqlExpression);
        }
        return result;
    }



    public List<XDynamicModel> queryBySql(String querySql,List<Object> params){
        DataAccessResult<List<XDynamicModel>> dataAccessResult = queryBySqlOperate(querySql,params);
        if(!dataAccessResult.getSuccessFlag()){
            throw new DalFrameException(dataAccessResult.getCode(),dataAccessResult.getException().getMessage());
        }
        return dataAccessResult.getResult();
    }

    public List<XDynamicModel> queryBySql(String querySql){
        DataAccessResult<List<XDynamicModel>> dataAccessResult = queryBySqlOperate(querySql,null);
        if(!dataAccessResult.getSuccessFlag()){
            throw new DalFrameException(dataAccessResult.getCode(),dataAccessResult.getException().getMessage());
        }
        return dataAccessResult.getResult();
    }

    public DataAccessResult<List<XDynamicModel>> queryBySqlOperate(String querySql,List<Object> params){


        DataAccessResult<List<XDynamicModel>> result = new DataAccessResult<>(SqlKey.QUERY_BY_SQL);
        SqlExpression sqlExpression = new SqlExpression(querySql,params,dataSource.getDataSourceTypeEnums());
        try {
            List<XDynamicModel> list = dataSource.executeQuery(sqlExpression.getFullSql(), sqlExpression.getParams(),
                    new XDynamicModelListHandler());
            result.setDone(list,sqlExpression);
        }catch (AutoProcRuntimeException autoProcRuntimeException){
            result.setError(ErrorCode.AUTOFILL_ERROR,autoProcRuntimeException, null);
        }catch (SqlBuilderException sqlException){
            result.setError(ErrorCode.SQL_BUILD_ERROR,sqlException, sqlExpression);
        }catch (SQLException sqlException){
            result.setError(ErrorCode.SQL_ERROR,sqlException, sqlExpression);
        }catch (DalFrameException e) {
            result.setError(e.getCode(),e, sqlExpression);
        }catch (Exception exception) {
            result.setError(ErrorCode.DAL_UNKNOWN_ERROR,exception, sqlExpression);
        }
        return result;
    }


    /**
     * 关闭一个事务
     *
     * @param transaction 被关闭的事务对象
     *
     */
    public void closeTransaction(IDbTransaction transaction) {
        try {
            if (transaction != null) {

                dataSource.closeTransaction(transaction);
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }

    @Override
    public void close() throws Exception {
        destroy();
    }

    /**
     * 查询方式类型
     */
    public enum SearchFor{
        /**
         * 主键
         */
        PK,
        /**
         * 唯一键
         */
        AK
    }


    /**
     * 销毁
     */
    public void destroy(){
        if(this.dataSource != null){
            this.dataSource.destroy();
        }
        this.isDestroyed = true;
    }
}
